import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:inmotion_pro/http/api_helper.dart';
import 'package:inmotion_pro/http/api_helper_tbox.dart';
import 'package:inmotion_pro/http/api_helper_vehicle.dart';
import 'package:inmotion_pro/pages/mixin/bluetooth_mixin.dart';
import 'package:inmotion_pro/pages/mixin/cache_mixin.dart';
import 'package:inmotion_pro/pages/others/common_enum/tbox_status_type.dart';
import 'package:inmotion_pro/service/global_service.dart';
import 'package:inmotion_pro/service/vehicle_connection_service.dart';

import 'realtime_data_server/realtime_data_service.dart';
import 'realtime_data_server/vehicle_realtime_data/vehicle_statistics_once.dart';

// 轮询定时器类型
enum BackendPollingTimerType {
  cyclingRecord("cycling_record"), // 上传骑行记录
  tboxOnlineStatus("tbox_online_status"), // 获取云盒在线状态
  wakeUpVehicle("wake_up_vehicle"); // 唤醒车辆

  final String tag;
  const BackendPollingTimerType(this.tag);
}

// App后台服务
class AppBackendService extends GetxService with CacheMixin, BluetoothMixin {
  // 单例
  static AppBackendService get to => Get.find();

  // 运行标志映射
  final Map<String, bool> _runningFlags = {};

  // 启动时间戳映射，用于记录每个tag的启动时间
  final Map<String, int> _startTimestamps = {};

  // 基于 Timer 的调度：每个 tag 对应一个 Timer
  final Map<String, Timer?> _timers = {};

  // 标记某个 tag 是否正在执行单次轮询（避免重叠）
  final Map<String, bool> _isExecuting = {};

  // 繁忙状态下上传骑行记录的轮询间隔（秒）
  final (BackendPollingTimerType, int) busyCyclingRecordTimerType =
      (BackendPollingTimerType.cyclingRecord, 5000);

  // 空闲状态下上传骑行记录的轮询间隔（秒）
  final (BackendPollingTimerType, int) idleCyclingRecordTimerType =
      (BackendPollingTimerType.cyclingRecord, 30000);

  // 云盒在线状态轮询间隔（秒）
  final (BackendPollingTimerType, int) tboxOnlineStatusTimerType =
      (BackendPollingTimerType.tboxOnlineStatus, 10000);

  // 唤醒车辆轮询间隔（秒）
  final (BackendPollingTimerType, int) wakeUpVehicleTimerType =
      (BackendPollingTimerType.wakeUpVehicle, 30000);

  // 当前轮询间隔映射
  final Map<String, int> _currentIntervals = {};

  // 开始轮询实时信息
  Future<bool> start({
    required List<(BackendPollingTimerType, int?)> types,
    bool immediate = false, // 是否立即执行一次
  }) async {
    for (final type in types) {
      final tag = type.$1.tag;

      // 如果已经在运行并有活跃的 Timer，则跳过
      if (_runningFlags[tag] == true && _timers[tag] != null) {
        continue;
      }

      // 标记为将要运行并初始化执行状态
      _runningFlags[tag] = true;
      _isExecuting[tag] = false;

      // 记录启动时间戳
      _startTimestamps[tag] = DateTime.now().millisecondsSinceEpoch;

      // 设置初始间隔
      _currentIntervals[tag] = type.$2 ?? 5000;

      // 取消旧的 Timer（如果有）
      try {
        _timers[tag]?.cancel();
      } catch (_) {}
      _timers[tag] = null;

      // 根据 immediate 参数决定执行方式
      if (immediate) {
        // 立即执行一次
        debugPrint("🟢【任务】$tag 立即执行一次");
        _runOnce(type.$1, _currentIntervals[tag]!);

        // 然后设置定时器继续执行
        _setupImmediateTimer(tag, type.$1, _currentIntervals[tag]!);
      } else {
        debugPrint("🟢【任务】$tag 延迟10s执行 -> 防止车辆部分数据还未正常初始化");
        // 延迟10秒后执行
        _timers[tag] = Timer(const Duration(seconds: 10), () {
          _timers[tag] = null;

          // 检查是否在延迟期间被停止
          if (_runningFlags[tag] != true) {
            debugPrint("🟡【轮询任务】$tag 在延迟期间已被停止，取消执行");
            _cleanupTag(tag);
            return;
          }

          // 检查启动时间戳是否匹配（防止旧的延迟任务执行）
          final startTime = _startTimestamps[tag];
          if (startTime == null) {
            debugPrint("🟡【轮询任务】$tag 启动时间戳丢失，取消执行");
            _cleanupTag(tag);
            return;
          }

          // 如果当前运行标志仍然为true，则执行任务
          if (_runningFlags[tag] == true) {
            _runOnce(type.$1, _currentIntervals[tag]!);
          } else {
            _cleanupTag(tag);
          }
        });
      }
    }
    return true;
  }

  // 设置立即执行的定时器
  void _setupImmediateTimer(
      String tag, BackendPollingTimerType timerType, int interval) {
    _timers[tag] = Timer.periodic(Duration(milliseconds: interval), (timer) {
      // 检查是否还在运行
      if (_runningFlags[tag] != true) {
        debugPrint("🟡【上传任务】$tag 已被停止，取消定时器");
        timer.cancel();
        _cleanupTag(tag);
        return;
      }
      // 执行任务
      _runOnce(timerType, interval);
    });
  }

  // 基于 Timer 的单次执行函数，完成后会在 runningFlags 为 true 时再次安排下一次
  Future<void> _runOnce(BackendPollingTimerType type, int milliseconds) async {
    // 在执行前再次检查运行状态
    final tag = type.tag;
    if (_runningFlags[tag] != true) {
      debugPrint("🟡【轮询任务】$tag 在执行前已被停止，取消执行");
      _cleanupTag(tag);
      return;
    }

    if (GlobalService.to.isUpgrading) {
      debugPrint('⚠️ 跳过轮询任务，因为当前正在进行固件升级');
      return;
    }

    if (_isExecuting[tag] == true) return; // 防止重叠执行

    _isExecuting[tag] = true;
    try {
      switch (type) {
        case BackendPollingTimerType.cyclingRecord:
          // 上传骑行记录任务
          await _uploadCyclingRecordTask();
          break;
        case BackendPollingTimerType.tboxOnlineStatus:
          // 获取云盒在线状态任务
          await _getTboxOnlineStatusTask();
          break;
        case BackendPollingTimerType.wakeUpVehicle:
          // 唤醒车辆任务
          await _wakeUpVehicleTask();
          break;
      }
    } catch (e) {
      debugPrint('runOnce[$tag] 异常: $e');
    } finally {
      _isExecuting[tag] = false;

      // 如果仍应继续运行，安排下一次（使用当前存储的间隔）
      if (_runningFlags[tag] == true) {
        final currentInterval = _currentIntervals[tag] ?? milliseconds;
        try {
          _timers[tag]?.cancel();
        } catch (_) {}
        _timers[tag] = Timer(Duration(milliseconds: currentInterval), () {
          _timers[tag] = null;
          _runOnce(type, currentInterval);
        });
      } else {
        // 清理 timer
        _cleanupTag(tag);
      }
    }
  }

  // 清理指定tag的资源
  void _cleanupTag(String tag) {
    try {
      _timers[tag]?.cancel();
    } catch (_) {}
    _timers.remove(tag);
    _currentIntervals.remove(tag);
    _isExecuting.remove(tag);
    _runningFlags.remove(tag);
    _startTimestamps.remove(tag);
  }

  // 上传骑行记录任务
  Future<void> _uploadCyclingRecordTask() async {
    try {
      // 在执行前再次检查运行状态
      final tag = BackendPollingTimerType.cyclingRecord.tag;
      if (_runningFlags[tag] != true) {
        debugPrint("🟡【上传任务】$tag 在任务执行前已被停止，取消上传");
        return;
      }

      // 检查车辆SN是否有效
      if (GlobalService.to.currentVehicleModel.value.sn.isEmpty) {
        disposeTimer(tag);
        return;
      }

      int fromIndex = await _getLatestUploadRecordIndex();
      List<VehicleStatisticsOnce> records =
          await _getVehicleFlashRideRecords(fromIndex, count: 3);

      if (records.isNotEmpty) {
        debugPrint("🚴‍♂️ 发现 ${records.length} 条新的骑行记录，开始上传...");

        // 上传逻辑
        bool uploadSuccess = await ApiHelper().uploadCyclingRecord(
          GlobalService.to.currentVehicleModel.value.sn,
          jsonEncode(records.map((e) => e.toMapToUploadServer()).toList()),
        );

        if (uploadSuccess) {
          debugPrint("✅ 骑行记录上传成功");
        } else {
          debugPrint("❌ 骑行记录上传失败");
        }
        // 有数据时设置为繁忙间隔（5秒）
        _updateTimerInterval(
            busyCyclingRecordTimerType.$1, busyCyclingRecordTimerType.$2);
      } else {
        // 没有数据时设置为空闲间隔（30秒）
        _updateTimerInterval(
            idleCyclingRecordTimerType.$1, idleCyclingRecordTimerType.$2);
      }
    } catch (e) {
      debugPrint("❌ 上传骑行记录任务发生异常: $e");
    }
  }

  // 获取云盒在线状态任务
  Future<void> _getTboxOnlineStatusTask() async {
    try {
      // 在执行前再次检查运行状态
      final tag = BackendPollingTimerType.tboxOnlineStatus.tag;
      if (_runningFlags[tag] != true) {
        debugPrint("🟡【获取云盒在线状态任务】$tag 在任务执行前已被停止，取消获取");
        return;
      }

      final model = GlobalService.to.currentVehicleModel.value;
      // 检查车辆SN是否有效，sn为空或无云盒则停止该任务
      if (model.sn.isEmpty || model.tboxStatus.value == TBoxStatus.none) {
        disposeTimer(tag);
        return;
      }

      final status = await ApiHelper().getTboxOnlineStatus(model.sn);
      switch (status.$1) {
        case TBoxStatus.online:
          // 更新车辆连接方式
          VechileConnectionService.to.updateVehicleConnectionMethod(status.$2);
          debugPrint("【云盒在线✅】&【车辆${status.$2 ? '在线✅' : '离线❌'}】");
          if (!status.$2) {
            // 车辆已休眠，启动唤醒任务
            start(types: [wakeUpVehicleTimerType], immediate: true);
          }
          break;
        case TBoxStatus.offline:
          debugPrint("【云盒离线❌】&【车辆${status.$2 ? '在线✅' : '离线❌'}】");
          disposeTimer(wakeUpVehicleTimerType.$1.tag);
          break;
        case TBoxStatus.none:
          debugPrint("⚠️【无云盒】⚠️");
          disposeTimer(wakeUpVehicleTimerType.$1.tag);
          break;
      }
      // 获取当前车辆，如果tboxStatus与hmicStatus有变化，则更新本地缓存
      if (model.tboxStatus.value == status.$1 &&
          model.hmicStatus == status.$2) {
        return;
      }
      // 更新本地缓存
      await cacheMixinUpdateCacheVehicle(
        model.bleName,
        tboxStatus: status.$1.rawValue,
        hmicStatus: status.$2 ? 1 : 0,
      );
    } catch (e) {
      disposeTimer(wakeUpVehicleTimerType.$1.tag);
      debugPrint("❌ 获取云盒在线状态任务发生异常: $e");
    }
  }

  // 唤醒车辆任务
  Future<void> _wakeUpVehicleTask() async {
    final tag = BackendPollingTimerType.wakeUpVehicle.tag;
    try {
      // 在执行前再次检查运行状态
      if (_runningFlags[tag] != true) {
        debugPrint("🟡【获取云盒在线状态任务】$tag 在任务执行前已被停止，取消获取");
        return;
      }

      final model = GlobalService.to.currentVehicleModel.value;

      // 检查车辆SN是否有效，sn为空或无云盒则停止该任务
      if (model.sn.isEmpty || model.hmicStatus) {
        disposeTimer(tag);
        return;
      }

      // 唤醒车辆
      bool wakeUpSuccess = await ApiHelper().wakeUpVehicle(model.sn);
      // 更新车辆连接方式
      VechileConnectionService.to.updateVehicleConnectionMethod(wakeUpSuccess);
      if (wakeUpSuccess) {
        debugPrint("✅✅✅ 唤醒车辆成功 ✅✅✅");
        // 更新本地缓存
        await cacheMixinUpdateCacheVehicle(
          model.bleName,
          hmicStatus: wakeUpSuccess ? 1 : 0,
        );
      } else {
        debugPrint("❌❌❌ 唤醒车辆失败 ❌❌❌");
        return;
      }
      // 唤醒完成，停止唤醒任务
      disposeTimer(tag);
    } catch (e) {
      disposeTimer(tag);
      debugPrint("❌ 唤醒车辆任务发生异常: $e");
    }
  }

  // 更新计时器间隔
  void _updateTimerInterval(BackendPollingTimerType type, int newIntervalMs) {
    final tag = type.tag;

    // 检查运行状态
    if (_runningFlags[tag] != true) {
      return;
    }

    final currentInterval = _currentIntervals[tag];

    // 如果间隔没有变化，不需要重新调度
    if (currentInterval == newIntervalMs) {
      return;
    }

    debugPrint("🟡 更新 [$tag] 轮询间隔: ${currentInterval}ms -> ${newIntervalMs}ms");
    _currentIntervals[tag] = newIntervalMs;

    // 如果当前没有正在执行，立即重新调度
    if (_isExecuting[tag] != true && _runningFlags[tag] == true) {
      try {
        _timers[tag]?.cancel();
      } catch (_) {}
      _timers[tag] = null;

      // 使用新的间隔立即重新调度
      _timers[tag] = Timer(Duration(milliseconds: newIntervalMs), () {
        _timers[tag] = null;
        _runOnce(type, newIntervalMs);
      });
    }
    // 如果正在执行，下一次执行时会自动使用新的间隔
  }

  // 获取服务端最新的上传记录index
  Future<int> _getLatestUploadRecordIndex() async {
    return ApiHelper()
        .getLatestRideRecordId(GlobalService.to.currentVehicleModel.value.sn);
  }

  // 获取车辆flash中的骑行记录
  Future<List<VehicleStatisticsOnce>> _getVehicleFlashRideRecords(
    int fromIndex, {
    int count = 3,
  }) {
    return RealTimeDataService.to
        .getRealtimeStatisticsOnce(toUpdateGlobal: false)
        .then((rsp1) {
      int flashCount = (rsp1?.count ?? 0) - 1; // 减去当前正在骑行的记录
      int flashIndex = rsp1?.index ?? 0;
      debugPrint(
          "🚴‍♂️ 服务端的骑行记录的最新index: $fromIndex, Flash中骑行记录的最新index: $flashIndex, Flash中骑行记录数量: $flashCount");
      if (flashCount <= 0 || fromIndex >= flashCount) {
        return Future.value(<VehicleStatisticsOnce>[]);
      } else {
        int needCount = (flashIndex - fromIndex > flashCount)
            ? flashCount
            : flashIndex - fromIndex;
        needCount = needCount > count ? count : needCount;
        List<Future<VehicleStatisticsOnce?>> futures = [];
        for (int i = flashIndex - 1; i >= flashIndex - needCount; i--) {
          if (i >= 0) {
            futures.add(RealTimeDataService.to.getRealtimeStatisticsOnce(
                toUpdateGlobal: false, startIndex: i, count: 1));
          }
        }
        return Future.wait(futures).then(
            (results) => results.whereType<VehicleStatisticsOnce>().toList());
      }
    });
  }

  // 停止轮询实时信息
  Future<bool> stop() {
    _stopTimer();
    return Future(() => true);
  }

  // 销毁轮询实时信息
  void disposeTimer(String tag) {
    _runningFlags[tag] = false;
    try {
      _timers[tag]?.cancel();
    } catch (_) {}
    _timers.remove(tag);
    _isExecuting.remove(tag);
    _runningFlags.remove(tag);
    _startTimestamps.remove(tag);
    debugPrint("🟥【销毁后台轮询任务】: $tag");
  }

  // 停止所有轮询
  void _stopTimer() {
    // 将所有运行标志设置为 false
    for (final key in _runningFlags.keys.toList()) {
      _runningFlags[key] = false;
    }
    // 取消并清理所有 timers
    _timers.forEach((_, t) {
      try {
        t?.cancel();
      } catch (_) {}
    });
    _timers.clear();
    _isExecuting.clear();
    _runningFlags.clear();
    _startTimestamps.clear();
    debugPrint("🛑【终止后台轮询任务】");
  }
}
